This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

source("tianfengRwrappers.R")
ds2 <- readRDS("ds2.rds")
selected_features <- read.csv("./datatable/ds2_features.csv", stringsAsFactors = F)
selected_features <- selected_features$Feature
Idents(ds2) <- ds2$seurat_clusters
ggobj <- multi_featureplot(selected_features[1:9], ds2, labels = NULL)
ggsave("ds2_features.png", device = png, height = 8, width = 8, plot = ggobj)

umap plot

ggsave("./fig2/ds2_ACumap.png", device = png, height = 4, width = 6, 
       plot = umapplot(ds2_AC, group.by = "Classification1", label.size = 5))
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the
existing scale.
ggsave("./fig2/ds2_PAumap.png", device = png, height = 4, width = 6, 
       plot = umapplot(ds2_PA, group.by = "Classification1", label.size = 5))
Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the
existing scale.

umapplot(ds2_AC,) umapplot(ds2_PA, group.by = “Classification1”)

Where is the Fibromyocyte

LUM

sep = 0.3
surfaceplot2("LUM",ds2,x_seq = seq(-2,13, sep), y_seq = seq(2,17,sep))

addmodulescore

geneset <- read.table("SMC")

ds2_AC <- AddModuleScore(ds2_AC,features = geneset, name = 'SMC_score')
ds2_PA <- AddModuleScore(ds2_PA,features = geneset, name = 'SMC_score')

(f("SMC_score1",label = F, ds2_AC) + scale_colour_gradient(low="#1E90FF", high="#ff2121")) %>%
  ggsave("./fig2/ds2_AC_SMCscore.png", device = png, height = 4, width = 5, plot = .)
(f("SMC_score1",label = F, ds2_PA) + scale_colour_gradient(low="#1E90FF", high="#ff2121")) %>%
  ggsave("./fig2/ds2_PA_SMCscore.png", device = png, height = 4, width = 5, plot = .)


# dataset1 <- AddModuleScore_UCell(dataset1,features = geneset, name = 'fibromyo_score')


geneset <- read.table("FB")

ds2_AC <- AddModuleScore(ds2_AC,features = geneset, name = 'FB_score')
ds2_PA <- AddModuleScore(ds2_PA,features = geneset, name = 'FB_score')

(f("FB_score1", label = F, ds2_AC) +scale_colour_gradient(low="#1E90FF", high="#ff2121")) %>%
  ggsave("./fig2/ds2_AC_FBscore.png", device = png, height = 4, width = 5, plot = .)
(f("FB_score1", label = F, ds2_PA) +scale_colour_gradient(low="#1E90FF", high="#ff2121")) %>%
  ggsave("./fig2/ds2_PA_FBscore.png", device = png, height = 4, width = 5, plot = .)

key features have gradient expression

BGN LUM

ridgetheme <- theme(plot.title = element_text(size = 15,color="black",hjust = 0.5),
                 axis.title = element_text(size = 15,color ="black"), 
                 axis.text = element_text(size = 15,color = "black"),
                 panel.grid.minor.y = element_blank(),
                 panel.grid.minor.x = element_blank(),
                 axis.text.x = element_text(angle = 0, hjust = 1),
                 panel.grid=element_blank(),
                 legend.position = "top",
                 legend.text = element_text(size= 15),
                 legend.title= element_text(size= 15)) 

ridge plot

df <- FetchData(ds2_AC,vars = c("FB_score1","SMC_score1","BGN","LUM","UMAP_1","UMAP_2"))
# df <- arrange(df,FB_score1,by_group = F)
data <- cbind(df,index = 1:nrow(df),cluster = Idents(ds2_AC))

(ggplot(data,aes(x=SMC_score1)) + geom_point(aes(y = BGN, color = cluster),alpha = 1) + geom_smooth(aes(y = BGN), color = "red") + theme_classic() + ridgetheme + scale_y_continuous(limits = c(1,5)) + scale_color_manual(values = colors_list) + theme(legend.key.size = unit(1,"cm")) + guides(colour = guide_legend(override.aes = list(size=10)))) 

(ggplot(data,aes(x=FB_score1)) + geom_point(aes(y = LUM, color = cluster),alpha = 1) + geom_smooth(aes(y = BGN), color = "green") + theme_classic() + ridgetheme +scale_y_continuous(limits = c(1,5)) + scale_color_manual(values = colors_list) + guides(colour = guide_legend(override.aes = list(size=10))))


df <- FetchData(ds2_PA,vars = c("FB_score1","SMC_score1","BGN","LUM","UMAP_1","UMAP_2"))
# df <- arrange(df,FB_score1,by_group = F)
data <- cbind(df,index = 1:nrow(df),cluster = Idents(ds2_PA))

ggplot(data,aes(x=SMC_score1)) + geom_point(aes(y = BGN, color = cluster),alpha = 1) + geom_smooth(aes(y = BGN), color = "red") + theme_classic() + ridgetheme + scale_y_continuous(limits = c(1,5)) + scale_color_manual(values = colors_list) + guides(colour = guide_legend(override.aes = list(size=10)))

ggplot(data,aes(x=FB_score1)) + geom_point(aes(y = LUM, color = cluster),alpha = 1) + geom_smooth(aes(y = BGN), color = "green") + theme_classic() + ridgetheme +scale_y_continuous(limits = c(1,5)) + scale_color_manual(values = colors_list) + guides(colour = guide_legend(override.aes = list(size=10)))

# ggplot(data,aes(x=FB_score1)) + geom_point(aes(y = BGN),color = "#e2b398",alpha = 1) + geom_smooth(aes(y = BGN), color = "red") + geom_point(aes(y=LUM),color = "#d1eba8",alpha = 1) + geom_smooth(aes(y = LUM), color = "green") + theme_classic() + ridgetheme +scale_y_continuous(limits = c(1,5))

fig.D

AC->PA

confuse_mat <- XGBoost_predict_from_seuobj(ds2_PA, bst_model, return_confuse_matrix = T)
Warning in XGBoost_predict_from_seuobj(ds2_PA, bst_model, return_confuse_matrix = T) :
  强制改变过程中产生了NA
Warning in XGBoost_predict_from_seuobj(ds2_PA, bst_model, return_confuse_matrix = T) :
  Please ensure that seurat idents are in numeric forms
[1] "ARI = 0.682835569069112"
confuse_mat <- XGBoost_predict_from_seuobj(ds2_PA, bst_model, return_confuse_matrix = T)
Warning in XGBoost_predict_from_seuobj(ds2_PA, bst_model, return_confuse_matrix = T) :
  强制改变过程中产生了NA
Warning in XGBoost_predict_from_seuobj(ds2_PA, bst_model, return_confuse_matrix = T) :
  Please ensure that seurat idents are in numeric forms
[1] "ARI = 0.682835569069112"
sankey_plot(confuse_mat,session = "AC -> PA")

numerical umap

embedding <- FetchData(object = ds2_PA, vars = c("UMAP_1", "UMAP_2"))
embedding <- cbind(embedding, cbind(ds2_PA$X0,ds2_PA$X1,ds2_PA$X2,ds2_PA$X3))

ggobj <- ggplot() +
  geom_point(data = embedding[embedding$`1`>0.1,], 
             aes(x = UMAP_1, y = UMAP_2, color = `1`), shape=16, size = 3, alpha=0.5) + 
  scale_color_gradient('0', low = "#FFFFFF00", high = "#6dc0a6") +
  new_scale("color") +
    geom_point(data = embedding[embedding$`2`>0.1,], 
             aes(x = UMAP_1, y = UMAP_2, color = `2`),shape=16, size = 3, alpha=0.5) + 
  scale_color_gradient('1', low = "#FFFFFF00", high = "#e2b398") +
   new_scale("color") +
    geom_point(data = embedding[embedding$`3`>0.1,], 
             aes(x = UMAP_1, y = UMAP_2, color = `3`),shape=16, size = 3, alpha=0.5) + 
  scale_color_gradient('2', low = "#FFFFFF00", high = "#e2a2ca") +
  new_scale("color") +
    geom_point(data = embedding[embedding$`4`>0.1,], 
             aes(x = UMAP_1, y = UMAP_2, color = `4`),shape=16, size = 3, alpha=0.5) + 
  scale_color_gradient('3', low = "#FFFFFF00", high = "#d1eba8") +
        xlab("UMAP 1") + ylab("UMAP 2")  +
        theme(axis.line = element_line(arrow = arrow(length = unit(0.2, "cm")))) +
        scale_y_continuous(breaks = NULL) +
        scale_x_continuous(breaks = NULL) + 
  theme(panel.background = element_blank(), panel.grid = element_blank(), legend.position = "bottom")
ggsave("./fig2/sup_ds2PA_umap.png",device = png, plot = ggobj, height = 10,width = 10)

PA->AC

train on PA

numerical umap

ggsave("./fig2/sup_ds2AC_umap.png",device = png, plot = ggobj,height = 10,width = 10)
Error in FUN(X[[i]], ...) : 找不到对象'0'

GSVA

GSVAres <- readRDS("GSVAres.rds")
es <- data.frame(t(GSVAres),stringsAsFactors=F)  #可视化相关通路的在umap上聚集情况
ds2_AC <- AddMetaData(ds2_AC, es)
f("CUI_TCF21_TARGETS_UP", label = F, ds2_AC) +scale_colour_gradient(low="#1E90FF", high="#ff2121")

ds2_PA <- AddMetaData(ds2_PA, es)
f("CUI_TCF21_TARGETS_UP", label = F, ds2_PA) +scale_colour_gradient(low="#1E90FF", high="#ff2121")

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ3RybCtTaGlmdCtFbnRlciouIAoKYGBge3J9CnNvdXJjZSgidGlhbmZlbmdSd3JhcHBlcnMuUiIpCmRzMiA8LSByZWFkUkRTKCJkczIucmRzIikKc2VsZWN0ZWRfZmVhdHVyZXMgPC0gcmVhZC5jc3YoIi4vZGF0YXRhYmxlL2RzMl9mZWF0dXJlcy5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzID0gRikKc2VsZWN0ZWRfZmVhdHVyZXMgPC0gc2VsZWN0ZWRfZmVhdHVyZXMkRmVhdHVyZQpJZGVudHMoZHMyKSA8LSBkczIkc2V1cmF0X2NsdXN0ZXJzCmdnb2JqIDwtIG11bHRpX2ZlYXR1cmVwbG90KHNlbGVjdGVkX2ZlYXR1cmVzWzE6OV0sIGRzMiwgbGFiZWxzID0gTlVMTCkKZ2dzYXZlKCJkczJfZmVhdHVyZXMucG5nIiwgZGV2aWNlID0gcG5nLCBoZWlnaHQgPSA4LCB3aWR0aCA9IDgsIHBsb3QgPSBnZ29iaikKYGBgCgojIHVtYXAgcGxvdApgYGB7cn0KZ2dzYXZlKCIuL2ZpZzIvZHMyX0FDdW1hcC5wbmciLCBkZXZpY2UgPSBwbmcsIGhlaWdodCA9IDQsIHdpZHRoID0gNiwgCiAgICAgICBwbG90ID0gdW1hcHBsb3QoZHMyX0FDLCBncm91cC5ieSA9ICJDbGFzc2lmaWNhdGlvbjEiLCBsYWJlbC5zaXplID0gNSkpCmdnc2F2ZSgiLi9maWcyL2RzMl9QQXVtYXAucG5nIiwgZGV2aWNlID0gcG5nLCBoZWlnaHQgPSA0LCB3aWR0aCA9IDYsIAogICAgICAgcGxvdCA9IHVtYXBwbG90KGRzMl9QQSwgZ3JvdXAuYnkgPSAiQ2xhc3NpZmljYXRpb24xIiwgbGFiZWwuc2l6ZSA9IDUpKQpgYGAKdW1hcHBsb3QoZHMyX0FDLCkKdW1hcHBsb3QoZHMyX1BBLCBncm91cC5ieSA9ICJDbGFzc2lmaWNhdGlvbjEiKQoKIyBXaGVyZSBpcyB0aGUgRmlicm9teW9jeXRlCiMjIyBMVU0KYGBge3J9CnNlcCA9IDAuMwpzdXJmYWNlcGxvdDIoIkxVTSIsZHMyLHhfc2VxID0gc2VxKC0yLDEzLCBzZXApLCB5X3NlcSA9IHNlcSgyLDE3LHNlcCkpCmBgYAoKIyMgIGFkZG1vZHVsZXNjb3JlCmBgYHtyIGZpZy5oZWlnaHQ9MywgZmlnLndpZHRoPTN9CmdlbmVzZXQgPC0gcmVhZC50YWJsZSgiU01DIikKCmRzMl9BQyA8LSBBZGRNb2R1bGVTY29yZShkczJfQUMsZmVhdHVyZXMgPSBnZW5lc2V0LCBuYW1lID0gJ1NNQ19zY29yZScpCmRzMl9QQSA8LSBBZGRNb2R1bGVTY29yZShkczJfUEEsZmVhdHVyZXMgPSBnZW5lc2V0LCBuYW1lID0gJ1NNQ19zY29yZScpCgooZigiU01DX3Njb3JlMSIsbGFiZWwgPSBGLCBkczJfQUMpICsgc2NhbGVfY29sb3VyX2dyYWRpZW50KGxvdz0iIzFFOTBGRiIsIGhpZ2g9IiNmZjIxMjEiKSkgJT4lCiAgZ2dzYXZlKCIuL2ZpZzIvZHMyX0FDX1NNQ3Njb3JlLnBuZyIsIGRldmljZSA9IHBuZywgaGVpZ2h0ID0gNCwgd2lkdGggPSA1LCBwbG90ID0gLikKKGYoIlNNQ19zY29yZTEiLGxhYmVsID0gRiwgZHMyX1BBKSArIHNjYWxlX2NvbG91cl9ncmFkaWVudChsb3c9IiMxRTkwRkYiLCBoaWdoPSIjZmYyMTIxIikpICU+JQogIGdnc2F2ZSgiLi9maWcyL2RzMl9QQV9TTUNzY29yZS5wbmciLCBkZXZpY2UgPSBwbmcsIGhlaWdodCA9IDQsIHdpZHRoID0gNSwgcGxvdCA9IC4pCgoKIyBkYXRhc2V0MSA8LSBBZGRNb2R1bGVTY29yZV9VQ2VsbChkYXRhc2V0MSxmZWF0dXJlcyA9IGdlbmVzZXQsIG5hbWUgPSAnZmlicm9teW9fc2NvcmUnKQoKCmdlbmVzZXQgPC0gcmVhZC50YWJsZSgiRkIiKQoKZHMyX0FDIDwtIEFkZE1vZHVsZVNjb3JlKGRzMl9BQyxmZWF0dXJlcyA9IGdlbmVzZXQsIG5hbWUgPSAnRkJfc2NvcmUnKQpkczJfUEEgPC0gQWRkTW9kdWxlU2NvcmUoZHMyX1BBLGZlYXR1cmVzID0gZ2VuZXNldCwgbmFtZSA9ICdGQl9zY29yZScpCgooZigiRkJfc2NvcmUxIiwgbGFiZWwgPSBGLCBkczJfQUMpICtzY2FsZV9jb2xvdXJfZ3JhZGllbnQobG93PSIjMUU5MEZGIiwgaGlnaD0iI2ZmMjEyMSIpKSAlPiUKICBnZ3NhdmUoIi4vZmlnMi9kczJfQUNfRkJzY29yZS5wbmciLCBkZXZpY2UgPSBwbmcsIGhlaWdodCA9IDQsIHdpZHRoID0gNSwgcGxvdCA9IC4pCihmKCJGQl9zY29yZTEiLCBsYWJlbCA9IEYsIGRzMl9QQSkgK3NjYWxlX2NvbG91cl9ncmFkaWVudChsb3c9IiMxRTkwRkYiLCBoaWdoPSIjZmYyMTIxIikpICU+JQogIGdnc2F2ZSgiLi9maWcyL2RzMl9QQV9GQnNjb3JlLnBuZyIsIGRldmljZSA9IHBuZywgaGVpZ2h0ID0gNCwgd2lkdGggPSA1LCBwbG90ID0gLikKYGBgCgojIGtleSBmZWF0dXJlcyBoYXZlIGdyYWRpZW50IGV4cHJlc3Npb24KIyMgQkdOIExVTQpgYGB7cn0KcmlkZ2V0aGVtZSA8LSB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSxjb2xvcj0iYmxhY2siLGhqdXN0ID0gMC41KSwKICAgICAgICAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSxjb2xvciA9ImJsYWNrIiksIAogICAgICAgICAgICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsY29sb3IgPSAiYmxhY2siKSwKICAgICAgICAgICAgICAgICBwYW5lbC5ncmlkLm1pbm9yLnkgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgICAgcGFuZWwuZ3JpZC5taW5vci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAxKSwKICAgICAgICAgICAgICAgICBwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgICAgICAgICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPSAxNSksCiAgICAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlPSBlbGVtZW50X3RleHQoc2l6ZT0gMTUpKSAKYGBgCgojIyByaWRnZSBwbG90CmBgYHtyfQpkZiA8LSBGZXRjaERhdGEoZHMyX0FDLHZhcnMgPSBjKCJGQl9zY29yZTEiLCJTTUNfc2NvcmUxIiwiQkdOIiwiTFVNIiwiVU1BUF8xIiwiVU1BUF8yIikpCiMgZGYgPC0gYXJyYW5nZShkZixGQl9zY29yZTEsYnlfZ3JvdXAgPSBGKQpkYXRhIDwtIGNiaW5kKGRmLGluZGV4ID0gMTpucm93KGRmKSxjbHVzdGVyID0gSWRlbnRzKGRzMl9BQykpCgooZ2dwbG90KGRhdGEsYWVzKHg9U01DX3Njb3JlMSkpICsgZ2VvbV9wb2ludChhZXMoeSA9IEJHTiwgY29sb3IgPSBjbHVzdGVyKSxhbHBoYSA9IDEpICsgZ2VvbV9zbW9vdGgoYWVzKHkgPSBCR04pLCBjb2xvciA9ICJyZWQiKSArIHRoZW1lX2NsYXNzaWMoKSArIHJpZGdldGhlbWUgKyBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygxLDUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xvcnNfbGlzdCkgKyB0aGVtZShsZWdlbmQua2V5LnNpemUgPSB1bml0KDEsImNtIikpICsgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MTApKSkpIAoKKGdncGxvdChkYXRhLGFlcyh4PUZCX3Njb3JlMSkpICsgZ2VvbV9wb2ludChhZXMoeSA9IExVTSwgY29sb3IgPSBjbHVzdGVyKSxhbHBoYSA9IDEpICsgZ2VvbV9zbW9vdGgoYWVzKHkgPSBCR04pLCBjb2xvciA9ICJncmVlbiIpICsgdGhlbWVfY2xhc3NpYygpICsgcmlkZ2V0aGVtZSArc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMSw1KSkgKyBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JzX2xpc3QpICsgZ3VpZGVzKGNvbG91ciA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemU9MTApKSkpCgoKZGYgPC0gRmV0Y2hEYXRhKGRzMl9QQSx2YXJzID0gYygiRkJfc2NvcmUxIiwiU01DX3Njb3JlMSIsIkJHTiIsIkxVTSIsIlVNQVBfMSIsIlVNQVBfMiIpKQojIGRmIDwtIGFycmFuZ2UoZGYsRkJfc2NvcmUxLGJ5X2dyb3VwID0gRikKZGF0YSA8LSBjYmluZChkZixpbmRleCA9IDE6bnJvdyhkZiksY2x1c3RlciA9IElkZW50cyhkczJfUEEpKQoKZ2dwbG90KGRhdGEsYWVzKHg9U01DX3Njb3JlMSkpICsgZ2VvbV9wb2ludChhZXMoeSA9IEJHTiwgY29sb3IgPSBjbHVzdGVyKSxhbHBoYSA9IDEpICsgZ2VvbV9zbW9vdGgoYWVzKHkgPSBCR04pLCBjb2xvciA9ICJyZWQiKSArIHRoZW1lX2NsYXNzaWMoKSArIHJpZGdldGhlbWUgKyBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygxLDUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xvcnNfbGlzdCkgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZT0xMCkpKQoKZ2dwbG90KGRhdGEsYWVzKHg9RkJfc2NvcmUxKSkgKyBnZW9tX3BvaW50KGFlcyh5ID0gTFVNLCBjb2xvciA9IGNsdXN0ZXIpLGFscGhhID0gMSkgKyBnZW9tX3Ntb290aChhZXMoeSA9IEJHTiksIGNvbG9yID0gImdyZWVuIikgKyB0aGVtZV9jbGFzc2ljKCkgKyByaWRnZXRoZW1lICtzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygxLDUpKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xvcnNfbGlzdCkgKyBndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZT0xMCkpKQoKIyBnZ3Bsb3QoZGF0YSxhZXMoeD1GQl9zY29yZTEpKSArIGdlb21fcG9pbnQoYWVzKHkgPSBCR04pLGNvbG9yID0gIiNlMmIzOTgiLGFscGhhID0gMSkgKyBnZW9tX3Ntb290aChhZXMoeSA9IEJHTiksIGNvbG9yID0gInJlZCIpICsgZ2VvbV9wb2ludChhZXMoeT1MVU0pLGNvbG9yID0gIiNkMWViYTgiLGFscGhhID0gMSkgKyBnZW9tX3Ntb290aChhZXMoeSA9IExVTSksIGNvbG9yID0gImdyZWVuIikgKyB0aGVtZV9jbGFzc2ljKCkgKyByaWRnZXRoZW1lICtzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygxLDUpKQoKYGBgCgojIGZpZy5ECiMjIEFDLT5QQQpgYGB7cn0Kc291cmNlKCJYR0Jvb3N0X3dyYXBwZXIuUiIpCgpic3RfbW9kZWwgPC0gWEdCb29zdF90cmFpbl9mcm9tX3NldW9iaihkczJfQUMpCmRzMl9QQSA8LSBYR0Jvb3N0X3ByZWRpY3RfZnJvbV9zZXVvYmooZHMyX1BBLGJzdF9tb2RlbCkKCmNvbmZ1c2VfbWF0IDwtIFhHQm9vc3RfcHJlZGljdF9mcm9tX3NldW9iaihkczJfUEEsIGJzdF9tb2RlbCwgcmV0dXJuX2NvbmZ1c2VfbWF0cml4ID0gVCkKc2Fua2V5X3Bsb3QoY29uZnVzZV9tYXQsc2Vzc2lvbiA9ICJBQyAtPiBQQSIpCgp1bWFwcGxvdChkczJfUEEsZ3JvdXAuYnkgPSAicHJvamVjdGVkX2lkZW50cyIpCmRzMl9QQSA8LSBwcm9qZWN0MnJlZl9jZWxsdHlwZTIoZHMyX1BBLCBkczJfQUMpCnVtYXBwbG90KGRzMl9QQSxncm91cC5ieSA9ICJyZWZfY2VsbHR5cGUiLCByZXBlbCA9IFQsIGxhYmVsLnNpemUgPSA1KQpgYGAKIyMjIG51bWVyaWNhbCB1bWFwCmBgYHtyfQplbWJlZGRpbmcgPC0gRmV0Y2hEYXRhKG9iamVjdCA9IGRzMl9QQSwgdmFycyA9IGMoIlVNQVBfMSIsICJVTUFQXzIiKSkKZW1iZWRkaW5nIDwtIGNiaW5kKGVtYmVkZGluZywgY2JpbmQoZHMyX1BBJFgwLGRzMl9QQSRYMSxkczJfUEEkWDIsZHMyX1BBJFgzKSkKCmdnb2JqIDwtIGdncGxvdCgpICsKICBnZW9tX3BvaW50KGRhdGEgPSBlbWJlZGRpbmdbZW1iZWRkaW5nJGAxYD4wLjEsXSwgCiAgICAgICAgICAgICBhZXMoeCA9IFVNQVBfMSwgeSA9IFVNQVBfMiwgY29sb3IgPSBgMWApLCBzaGFwZT0xNiwgc2l6ZSA9IDMsIGFscGhhPTAuNSkgKyAKICBzY2FsZV9jb2xvcl9ncmFkaWVudCgnMCcsIGxvdyA9ICIjRkZGRkZGMDAiLCBoaWdoID0gIiM2ZGMwYTYiKSArCiAgbmV3X3NjYWxlKCJjb2xvciIpICsKICAgIGdlb21fcG9pbnQoZGF0YSA9IGVtYmVkZGluZ1tlbWJlZGRpbmckYDJgPjAuMSxdLCAKICAgICAgICAgICAgIGFlcyh4ID0gVU1BUF8xLCB5ID0gVU1BUF8yLCBjb2xvciA9IGAyYCksc2hhcGU9MTYsIHNpemUgPSAzLCBhbHBoYT0wLjUpICsgCiAgc2NhbGVfY29sb3JfZ3JhZGllbnQoJzEnLCBsb3cgPSAiI0ZGRkZGRjAwIiwgaGlnaCA9ICIjZTJiMzk4IikgKwogICBuZXdfc2NhbGUoImNvbG9yIikgKwogICAgZ2VvbV9wb2ludChkYXRhID0gZW1iZWRkaW5nW2VtYmVkZGluZyRgM2A+MC4xLF0sIAogICAgICAgICAgICAgYWVzKHggPSBVTUFQXzEsIHkgPSBVTUFQXzIsIGNvbG9yID0gYDNgKSxzaGFwZT0xNiwgc2l6ZSA9IDMsIGFscGhhPTAuNSkgKyAKICBzY2FsZV9jb2xvcl9ncmFkaWVudCgnMicsIGxvdyA9ICIjRkZGRkZGMDAiLCBoaWdoID0gIiNlMmEyY2EiKSArCiAgbmV3X3NjYWxlKCJjb2xvciIpICsKICAgIGdlb21fcG9pbnQoZGF0YSA9IGVtYmVkZGluZ1tlbWJlZGRpbmckYDRgPjAuMSxdLCAKICAgICAgICAgICAgIGFlcyh4ID0gVU1BUF8xLCB5ID0gVU1BUF8yLCBjb2xvciA9IGA0YCksc2hhcGU9MTYsIHNpemUgPSAzLCBhbHBoYT0wLjUpICsgCiAgc2NhbGVfY29sb3JfZ3JhZGllbnQoJzMnLCBsb3cgPSAiI0ZGRkZGRjAwIiwgaGlnaCA9ICIjZDFlYmE4IikgKwogICAgICAgIHhsYWIoIlVNQVAgMSIpICsgeWxhYigiVU1BUCAyIikgICsKICAgICAgICB0aGVtZShheGlzLmxpbmUgPSBlbGVtZW50X2xpbmUoYXJyb3cgPSBhcnJvdyhsZW5ndGggPSB1bml0KDAuMiwgImNtIikpKSkgKwogICAgICAgIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBOVUxMKSArCiAgICAgICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IE5VTEwpICsgCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCmdnc2F2ZSgiLi9maWcyL3N1cF9kczJQQV91bWFwLnBuZyIsZGV2aWNlID0gcG5nLCBwbG90ID0gZ2dvYmosIGhlaWdodCA9IDEwLHdpZHRoID0gMTApCmBgYAoKCgojIyBQQS0+QUMKIyMjIHRyYWluIG9uIFBBCmBgYHtyfQpic3RfbW9kZWwgPC0gWEdCb29zdF90cmFpbl9mcm9tX3NldW9iaihkczJfUEEpCmRzMl9BQyA8LSBYR0Jvb3N0X3ByZWRpY3RfZnJvbV9zZXVvYmooZHMyX0FDLGJzdF9tb2RlbCkKdW1hcHBsb3QoZHMyX0FDLGdyb3VwLmJ5ID0gInByb2plY3RlZF9pZGVudHMiKQpkczJfQUMgPC0gcHJvamVjdDJyZWZfY2VsbHR5cGUyKGRzMl9BQyxkczJfUEEpCnVtYXBwbG90KGRzMl9BQyxncm91cC5ieSA9ICJyZWZfY2VsbHR5cGUiLCByZXBlbCA9IFQsIGxhYmVsLnNpemUgPSA1KQoKY29uZnVzZV9tYXQgPC0gWEdCb29zdF9wcmVkaWN0X2Zyb21fc2V1b2JqKGRzMl9BQywgYnN0X21vZGVsLCByZXR1cm5fY29uZnVzZV9tYXRyaXggPSBUKQpzYW5rZXlfcGxvdChjb25mdXNlX21hdCxzZXNzaW9uID0gIlBBIC0+IEFDIikKYGBgCiMjIyBudW1lcmljYWwgdW1hcApgYGB7cn0KZW1iZWRkaW5nIDwtIEZldGNoRGF0YShvYmplY3QgPSBkczJfQUMsIHZhcnMgPSBjKCJVTUFQXzEiLCAiVU1BUF8yIikpCmVtYmVkZGluZyA8LSBjYmluZChlbWJlZGRpbmcsIGNiaW5kKGRzMl9BQyRYMCxkczJfQUMkWDEsZHMyX0FDJFgyLGRzMl9BQyRYMykpCgpnZ29iaiA8LSBnZ3Bsb3QoKSArCiAgZ2VvbV9wb2ludChkYXRhID0gZW1iZWRkaW5nW2VtYmVkZGluZyRgMWA+MC4xLF0sIAogICAgICAgICAgICAgYWVzKHggPSBVTUFQXzEsIHkgPSBVTUFQXzIsIGNvbG9yID0gYDFgKSwgc2hhcGU9MTYsIHNpemUgPSAzLCBhbHBoYT0wLjUpICsgCiAgc2NhbGVfY29sb3JfZ3JhZGllbnQoJzAnLCBsb3cgPSAiI0ZGRkZGRjAwIiwgaGlnaCA9ICIjNmRjMGE2IikgKwogIG5ld19zY2FsZSgiY29sb3IiKSArCiAgICBnZW9tX3BvaW50KGRhdGEgPSBlbWJlZGRpbmdbZW1iZWRkaW5nJGAyYD4wLjEsXSwgCiAgICAgICAgICAgICBhZXMoeCA9IFVNQVBfMSwgeSA9IFVNQVBfMiwgY29sb3IgPSBgMmApLHNoYXBlPTE2LCBzaXplID0gMywgYWxwaGE9MC41KSArIAogIHNjYWxlX2NvbG9yX2dyYWRpZW50KCcxJywgbG93ID0gIiNGRkZGRkYwMCIsIGhpZ2ggPSAiI2UyYjM5OCIpICsKICAgbmV3X3NjYWxlKCJjb2xvciIpICsKICAgIGdlb21fcG9pbnQoZGF0YSA9IGVtYmVkZGluZ1tlbWJlZGRpbmckYDNgPjAuMSxdLCAKICAgICAgICAgICAgIGFlcyh4ID0gVU1BUF8xLCB5ID0gVU1BUF8yLCBjb2xvciA9IGAzYCksc2hhcGU9MTYsIHNpemUgPSAzLCBhbHBoYT0wLjUpICsgCiAgc2NhbGVfY29sb3JfZ3JhZGllbnQoJzInLCBsb3cgPSAiI0ZGRkZGRjAwIiwgaGlnaCA9ICIjZTJhMmNhIikgKwogIG5ld19zY2FsZSgiY29sb3IiKSArCiAgICBnZW9tX3BvaW50KGRhdGEgPSBlbWJlZGRpbmdbZW1iZWRkaW5nJGA0YD4wLjEsXSwgCiAgICAgICAgICAgICBhZXMoeCA9IFVNQVBfMSwgeSA9IFVNQVBfMiwgY29sb3IgPSBgNGApLHNoYXBlPTE2LCBzaXplID0gMywgYWxwaGE9MC41KSArIAogIHNjYWxlX2NvbG9yX2dyYWRpZW50KCczJywgbG93ID0gIiNGRkZGRkYwMCIsIGhpZ2ggPSAiI2QxZWJhOCIpICsKICAgICAgICB4bGFiKCJVTUFQIDEiKSArIHlsYWIoIlVNQVAgMiIpICArCiAgICAgICAgdGhlbWUoYXhpcy5saW5lID0gZWxlbWVudF9saW5lKGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgwLjIsICJjbSIpKSkpICsKICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gTlVMTCkgKwogICAgICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBOVUxMKSArIAogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQpnZ3NhdmUoIi4vZmlnMi9zdXBfZHMyQUNfdW1hcC5wbmciLGRldmljZSA9IHBuZywgcGxvdCA9IGdnb2JqLGhlaWdodCA9IDEwLHdpZHRoID0gMTApCmBgYAoKCiMgR1NWQQpgYGB7cn0KR1NWQXJlcyA8LSByZWFkUkRTKCJHU1ZBcmVzLnJkcyIpCmVzIDwtIGRhdGEuZnJhbWUodChHU1ZBcmVzKSxzdHJpbmdzQXNGYWN0b3JzPUYpICAj5Y+v6KeG5YyW55u45YWz6YCa6Lev55qE5ZyodW1hcOS4iuiBmumbhuaDheWGtQpkczJfQUMgPC0gQWRkTWV0YURhdGEoZHMyX0FDLCBlcykKZigiQ1VJX1RDRjIxX1RBUkdFVFNfVVAiLCBsYWJlbCA9IEYsIGRzMl9BQykgK3NjYWxlX2NvbG91cl9ncmFkaWVudChsb3c9IiMxRTkwRkYiLCBoaWdoPSIjZmYyMTIxIikKCmRzMl9QQSA8LSBBZGRNZXRhRGF0YShkczJfUEEsIGVzKQpmKCJDVUlfVENGMjFfVEFSR0VUU19VUCIsIGxhYmVsID0gRiwgZHMyX1BBKSArc2NhbGVfY29sb3VyX2dyYWRpZW50KGxvdz0iIzFFOTBGRiIsIGhpZ2g9IiNmZjIxMjEiKQpgYGAKCkFkZCBhIG5ldyBjaHVuayBieSBjbGlja2luZyB0aGUgKkluc2VydCBDaHVuayogYnV0dG9uIG9uIHRoZSB0b29sYmFyIG9yIGJ5IHByZXNzaW5nICpDdHJsK0FsdCtJKi4KCldoZW4geW91IHNhdmUgdGhlIG5vdGVib29rLCBhbiBIVE1MIGZpbGUgY29udGFpbmluZyB0aGUgY29kZSBhbmQgb3V0cHV0IHdpbGwgYmUgc2F2ZWQgYWxvbmdzaWRlIGl0IChjbGljayB0aGUgKlByZXZpZXcqIGJ1dHRvbiBvciBwcmVzcyAqQ3RybCtTaGlmdCtLKiB0byBwcmV2aWV3IHRoZSBIVE1MIGZpbGUpLgoKVGhlIHByZXZpZXcgc2hvd3MgeW91IGEgcmVuZGVyZWQgSFRNTCBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBDb25zZXF1ZW50bHksIHVubGlrZSAqS25pdCosICpQcmV2aWV3KiBkb2VzIG5vdCBydW4gYW55IFIgY29kZSBjaHVua3MuIEluc3RlYWQsIHRoZSBvdXRwdXQgb2YgdGhlIGNodW5rIHdoZW4gaXQgd2FzIGxhc3QgcnVuIGluIHRoZSBlZGl0b3IgaXMgZGlzcGxheWVkLgo=